package dao;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;


import pojo.Aluno;
import pojo.Disciplina;
import pojo.Professor;
import pojo.AlunoTurma;
import pojo.Turma;

public class TurmaDaoImp implements TurmaDao {

	private List<Turma> turmas;
	private static int nextId;
	
	public TurmaDaoImp() {
		this.turmas = new ArrayList<Turma>();
		loadData();
	}
	public void loadData() {
		try{
			File in = new File("files/Turma.txt");
			InputStream fileLeitura = new  FileInputStream(in);
			InputStreamReader wLeitura = new InputStreamReader(fileLeitura);
			BufferedReader bufLeitura = new BufferedReader(wLeitura);

			String linha = bufLeitura.readLine();
			this.turmas.clear();
			Turma aux;
			
			while(linha!= null) {
				String s[] = linha.split("\\t");
				List<Integer> alunos = new ArrayList<Integer>();
				int numAlunos = Integer.parseInt(s[8]);
				for (int i = 0; i < numAlunos; i++) {
					alunos.add(Integer.parseInt(s[9+i]));
				}
				
				List<Integer> atividades = new ArrayList<Integer>();
				int numAtividades =  Integer.parseInt(s[9+numAlunos]);
				int inicioAtividades = 10+numAlunos;
				for (int i = 0; i < numAtividades; i++) {
					atividades.add(Integer.parseInt(s[inicioAtividades+i]));
				}
				
				
				aux = new Turma(Integer.parseInt(s[0]), Integer.parseInt(s[1]),
						Integer.parseInt(s[2]), s[3], s[4],
						Integer.parseInt(s[5]), Integer.parseInt(s[6]),
						Integer.parseInt(s[7]), alunos,atividades);
				this.turmas.add(aux);
				linha = bufLeitura.readLine();
			}
			
			bufLeitura.close();
			wLeitura.close();
			fileLeitura.close();
		} catch (NumberFormatException e) {
			String erro = "ERRO: Dados de Turmas corrompidos." +
					"\nFeche seus trabalhos e solicite ao administrador" +
					" uma restauracao deste sistema.";
			System.out.println(erro);
			// throw new IOException(erro);
		} catch (IOException e) {
			String erro = "Aviso: Nao foi possivel encontrar os dados das " +
					"Turmas. Se esta for a primeira execucao do sistema " +
					"por favor desconsidere o problema, caso contrario " +
					"feche o programa e contate o administrador.";
			System.out.println(erro);
			// throw new IOException(erro);
		}
		updateNextId();
	}
	@Override
	public void saveData() {
		try{
			File out = new File("files/Turma.txt");
			OutputStream fileEscrita = new  FileOutputStream(out);
			OutputStreamWriter wEscrita = new OutputStreamWriter(fileEscrita);  
			BufferedWriter bufEscrita = new BufferedWriter(wEscrita);
					
			for (Turma turma : this.turmas) {
				bufEscrita.write(turma.toStringIDs()+"\n");
			}
			
			bufEscrita.close();
			wEscrita.close();
			fileEscrita.close();
		} catch (IOException e) {
			System.out.println("ERRO: Nao foi possivel salvar os dados das " +
					"Turmas no sistema."
					+ "\nContate o administrador e informe este erro.");
		}
//		updateNextId();
	}
	@Override
	public boolean add(Turma turma) {
		if (!turmas.contains(turma)) {	
			this.turmas.add(turma);
			updateNextId();
			saveData();
			return true;
		} else {
			return false;
		}
	}
	@Override
	public boolean delete(Turma turma) {
		// TODO Auto-generated method stub
		return false;
	}
	@Override
	public Turma get(int id) {
		for (Turma turma : turmas) {
			if(turma.getId() == id) {
				return turma;
			}
		}
		return null;
	}
	@Override
	public ArrayList<Turma> getByProfessor(Professor professor) {
		ArrayList<Turma> turmasDeProfessor = new ArrayList<Turma>();
		for (Turma turma : turmas) {
			if(turma.getProfessor() == professor.getId()) {
				turmasDeProfessor.add(turma);
			}
		}
		return turmasDeProfessor;
	}
	@Override
	public List<Turma> getByDisciplinaAnoPeriodo(int disciplina, int ano,
			int periodo) {
		List<Turma> retorno = new ArrayList<Turma>();
		for (Turma turma : this.turmas) {
			if (turma.getDisciplina() == disciplina &&
				turma.getAno() == ano &&
				turma.getPeriodo() == periodo){
				retorno.add(turma);
			}
		}
		if (retorno.size() == 0) {
			return null;
		}
		return retorno;
	}
	@Override
	public List<AlunoTurma> situacaoAluno(List<Turma> turmas, Disciplina disciplina, Aluno aluno, AlunoTurmaDao alTurmaDao) {
		List<AlunoTurma> retorno = new ArrayList<AlunoTurma>();
		for (Turma turma : turmas) {
			if (turma.getDisciplina() == disciplina.getId()) {
				retorno.add(alTurmaDao.getByAmbos(turma.getId(), aluno.getId()));
			}
		}
		if (retorno.isEmpty()) {
			return null;
		}
		return retorno;
	}
	@Override
	public List<Disciplina> disciplinasByList(List<Turma> turmas, DisciplinaDao disciplinaDao) {
		List<Disciplina> retorno = new ArrayList<Disciplina>();
		for (Turma turma : turmas) {
			if (!retorno.contains(disciplinaDao.get(turma.getDisciplina()))) {
				retorno.add(disciplinaDao.get(turma.getDisciplina()));
			}
		}
		if (retorno.isEmpty()) {
			return null;
		}
		return retorno;
	}
	@Override
	public int numeroOfertasPorDisciplina(int disciplina) {
		int n = 0;
		for (Turma turma : turmas) {
			if (turma.getDisciplina() == disciplina) {
				n++;
			}
		}
		return n;
	}
	@Override
	public int numeroDisciplinasPorProfessor(int professor) {
		List<Turma> turmasDoProfessor = new ArrayList<Turma>();
		for (Turma turma : turmas) {
			if (turma.getProfessor() == professor) {
				boolean novaDisciplina = true;
				for (Turma turmaDoProfessor : turmasDoProfessor) {
					if (turma.getDisciplina() == turmaDoProfessor.getDisciplina()) {
						novaDisciplina = false;
					}
				}
				if (novaDisciplina) {
					turmasDoProfessor.add(turma);
				}
			}
		}
		return turmasDoProfessor.size();
	}
	@Override
	public void listar() {
		System.out.println("--------------------");
		for (Turma turma : turmas) {
			System.out.println("-> "+turma);
		}
		System.out.println("--------------------");
	}
	public int nextId() {
		return nextId;
	}
	public void updateNextId() {
		int id = 0;
		while(hasId(id)){
			id++;
		}
		nextId = id;
		return;
	}
	@Override
	public boolean hasId(int id){
		for (Turma turma : turmas) {
			if(turma.getId() == id) {
				return true;
			}
		}
		return false;
	}
	public static int getNextId() {
		return nextId;
	}
	@Override
	public void listarPorProfessor(Professor professor) {
		System.out.println("--------------------");
		for (Turma turma : getByProfessor(professor)) {
			System.out.println("-> "+turma);
		}
		System.out.println("--------------------");	
	}
	public void listarPorDisciplina(Disciplina disciplina) {
		System.out.println("--------------------");
		for (Turma turma : getByDisciplina(disciplina)) {
			System.out.println("-> "+turma);
		}
		System.out.println("--------------------");	
	}
	public ArrayList<Turma> getByDisciplina(Disciplina disciplina) {
		ArrayList<Turma> retorno = new ArrayList<Turma>();
		for (Turma turma : turmas) {
			if (turma.getDisciplina() == disciplina.getId() ) {
				retorno.add(turma);
			}
		}
		return retorno;
	}
	@Override
	public boolean addAluno(Aluno aluno, Turma turma, AlunoTurmaDao regDao){
		if (!turma.containsAlunoCadastrado(aluno, regDao)) {
			AlunoTurma registro = new AlunoTurma(AlunoTurmaDaoImp.getNextId(), turma, aluno);
			return regDao.add(registro);
		}
		return false;
	}
	@Override
	public ArrayList<AlunoTurma> getByTurma(Turma turma, AlunoTurmaDao regDao) {
		ArrayList<AlunoTurma> registrosPorTurma = new ArrayList<AlunoTurma>();
		for (AlunoTurma registro : regDao.get()) {
			if(turma.getId() == registro.getTurmaId()) {
				registrosPorTurma.add(registro);
			}
		}
		return registrosPorTurma;
	}
	public boolean isEmpty() {
		return turmas.isEmpty();
	}
	@Override
	public void clearAll() {
		turmas.clear();
	}
	
	/*
	public static void main(String[] args){
		ArrayList<Integer> i = new ArrayList<Integer>();
		i.add(10);
		i.add(10);
		i.add(10);
		Turma turma = new Turma(14, 1, 2, "sjdr", "tarde", 29, 5, 3, i, i);
		System.out.println(turma.toStringIDs());
		TurmaDaoImp tD = new TurmaDaoImp();
		AlunoDaoImp aD = new AlunoDaoImp();
		aD.listar();
		System.out.print("digite  id do aluno: ");
		int id = Console.readInteger();  
		Aluno aluno = aD.get(id);
		if(!(tD.add(turma))){
			turma = tD.get(turma.getId());
		}
		
		
		RegistroDaoImp regDao = new RegistroDaoImp();
		if(tD.addAluno(aluno, turma, regDao)){
			System.out.println("aluno inserido com sucesso");;
		}else {
			System.out.println("Erro ao inserir, aluno ja cadastrado!");;
		}
		regDao.listar(aD);
		regDao.saveData();
	}
*/
}
